from typing import Union, List, Optional
from fastapi.responses import RedirectResponse
from fastapi import APIRouter, Depends, Body, Header, Query, Path, Form, UploadFile, File, Request
from fastapi.encoders import jsonable_encoder
from odoo.api import Environment
from odoo.addons.fastapi.dependencies import odoo_env
from odoo.addons.fastapi_odoo_bridge.core.response import custom_response
from odoo.addons.fastapi_odoo_bridge.core.header import set_lang
from ...basemodels.dto.center_area.center_area import OrderFilter, AddressDto, UserInfoDto, UserSecurityDto, CustomerCouponFilterDto, PopUpDto
from ...functions.center_area_func import CenterAreaFunc
from ...functions.router_fuc import RouterFunc
from ...basemodels.vo.center_area.user_center import OrderBaseForUserCenter, Address, ShipmentInvoice, UserInfo, CouponBase, OrderBaseForUserCenterVO, UserBalance
from ...basemodels.vo.common.first_level import RpShipOrder
from odoo.addons.basic_configuration.config.env_config import switch_env
from odoo.addons.basic_configuration.functions.logger import log
from ...handler.global_handler import AuthRouter
from odoo.addons.fastapi_odoo_bridge.core.basemodel import CommonResponse

router = AuthRouter(prefix='/user_route', tags=['用户中心'])

"""
订单相关
"""


@router.post(
    path='/get_or_filter/available/ship_order',
    summary='获取或过滤订单',
    description='获取或过滤订单',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_all_ship_order(
        order_filter: OrderFilter = Body(..., description='过滤条件'),
        env: Environment = Depends(odoo_env),
        Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    rp_ship_order_list, count = func.get_user_order_list(order_filter.user_id, order_filter.order_state, order_filter.page, order_filter.page_size, order_filter.order_by)
    rp_ship_order_list = [OrderBaseForUserCenter(__from_odoo=record, __env=env) for record in rp_ship_order_list]
    result = OrderBaseForUserCenterVO(order_list=rp_ship_order_list, amount=count)
    result = CommonResponse(code='200', msg='success', data=jsonable_encoder(result))
    return result


@router.get(
    path='/get/order/detail',
    summary='获取订单详情',
    description='获取订单详情',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_order_detail(order_id: int = Query(..., description='订单ID'), env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    order_detail = func.get_order_detail(order_id)
    order_detail = RpShipOrder(__from_odoo=order_detail, __env=env)
    # 填充所有所有增值服务明细
    all_available_value_added = RouterFunc(env).get_all_available_value_added(order_detail.shipper_mail_route.id)
    order_detail.available_value_added_list = all_available_value_added
    result = CommonResponse(code='200', msg='success', data=jsonable_encoder(order_detail))
    return result


@router.get(
    path='/get/shipment/label',
    description='获取运输单面单文件',
    summary='获取运输单面单文件',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_shipment_label(shipment_id: int = Query(..., description='运输单ID'), env: Environment = Depends(odoo_env),
                             order_id: int = Query(..., description='订单ID'), Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    response = func.get_shipment_label(shipment_id, order_id)
    return response


"""
用户信息相关
"""


@router.get(
    path='/get/user/address_book',
    summary='获取用户地址簿',
    description='获取用户地址簿',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def ger_user_address_book(user_id: int = Query(..., description='用户ID'), env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    result = func.ger_user_address_book(user_id)
    if not isinstance(result, dict):
        result = [Address(__from_odoo=record, __env=env) for record in result]
        result = CommonResponse(code='200', msg='success', data=jsonable_encoder(result))
    return result


@router.post(
    path='/save_or_edit/address_book',
    summary='编辑或保存地址信息',
    description='编辑或保存地址信息',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def edit_or_save_address_book(user_id: int = Query(..., description='用户ID'),
                                    address: AddressDto = Body(..., description='地址信息'),
                                    env: Environment = Depends(odoo_env),
                                    Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    result = func.edit_or_save_address_book(address, user_id)
    return result


@router.get(
    path='/delete/address_book/{address_book_id}',
    summary='逻辑删除某一项地址',
    description='逻辑删除某一项地址',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def delete_address_book(address_id: int = Path(..., description='用户ID', alias='address_book_id'),
                              env: Environment = Depends(odoo_env),
                              Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    response = func.delete_address_book(address_id)
    return response


@router.get(
    path='/get/user/info',
    description='获取用户信息',
    summary='获取用户信息',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_user_info(user_id: int = Query(..., description='用户ID'), env: Environment = Depends(odoo_env),
                        Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    response = func.get_user_info(user_id)
    if not isinstance(response, dict):
        response = UserInfo(__from_odoo=response, __env=env)
        response = CommonResponse(code='200', msg='success', data=jsonable_encoder(response))
    return response


@router.post(
    path='/edit/user/info',
    description='编辑用户信息',
    summary='编辑用户信息',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def edit_user_info(user_info: UserInfoDto = Body(..., description='用户信息'), env: Environment = Depends(odoo_env),
                         Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    response = func.edit_user_info(user_info)
    return response


@router.post(
    path='/modify/user/password',
    description='修改用户密码',
    summary='修改用户密码',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def modify_user_password(user_security: UserSecurityDto = Body(..., description='用户安全信息'), env: Environment = Depends(odoo_env),
                               Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    response = func.modify_user_password(user_security)
    return response


@router.delete(
    path='/delete/user/account',
    description='删除用户账户',
    summary='删除用户账户',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def delete_user_account(user_id: int = Query(..., description='用户ID'), env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    result = func.delete_user_account(user_id)
    return result


@router.post(
    path='/upload/profile',
    description='上传头像',
    summary='上传头像',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def upload_profile(profile: UploadFile = File(..., description='头像文件'), env: Environment = Depends(odoo_env),
                         user_id: int = Query(..., description='用户ID'),
                         Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    response = func.upload_profile(profile, user_id)
    return response


@router.get(
    path='/obtain/user/balance',
    description='获取用户的余额',
    summary='获取用户的余额',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def obtain_user_balance(user_id: int = Query(..., description='用户ID', alias='user_id'), env: Environment = Depends(odoo_env),
                              Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    result = func.obtain_user_balance(user_id)
    if not isinstance(result, dict):
        result = UserBalance(__from_odoo=result, __env=env)
        result = CommonResponse(code='200', msg='success', data=jsonable_encoder(result))
    return result


@router.post(
    path='/pop_up/user/balance',
    description='充值用户余额',
    summary='充值用户余额',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def pop_up_user_balance(request: Request, pop_up: PopUpDto = Body(..., description='充值'), env: Environment = Depends(odoo_env),
                              Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    result = func.pop_up_user_balance(pop_up, request)
    return result


@router.get(
    path='/pop_up/check/success',
    description='充值余额成功回调',
    summary='充值余额成功回调'
)
async def top_up_check_success(
        customer_id: int = Query(..., description='用户ID', alias='customer_id'),
        amount: int = Query(..., description='支付金额', alias='amount'),
        env: Environment = Depends(odoo_env)):
    func = CenterAreaFunc(env)
    func.top_up_check_success(customer_id, amount, env)
    url = '{}?top_up=successfully'.format(switch_env['h5_url']['url'])
    return RedirectResponse(url=url)


@router.get(
    path='/pop_up/check/cancel',
    description='充值余额失败回调',
    summary='充值余额失败回调',
)
async def top_up_check_cancel(customer_id: int = Query(..., description='用户ID', alias='customer_id'),
                              amount: int = Query(..., description='支付金额', alias='amount'),
                              env: Environment = Depends(odoo_env)):
    # TODO 充值失败记录
    url = '{}?top_up=fail'.format(switch_env['h5_url']['url'])
    return RedirectResponse(url=url)


@router.get(
    path='/obtain/user/invoice/list',
    description='获取用户发票列表',
    summary='获取用户发票列表',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def obtain_user_invoice_list(request: Request, env: Environment = Depends(odoo_env), Accept_Language: Optional[str] = Header()):
    # 获取登录用户ID
    login_user = request.session.get('order_customer_id')
    log('当前登录的用户ID是{}'.format(login_user))
    func = CenterAreaFunc(env)
    response = func.obtain_user_invoice_list(login_user)
    if not isinstance(response, dict):
        response = [ShipmentInvoice(__from_odoo=record, __env=env) for record in response]
        response = CommonResponse(code='200', msg='success', data=jsonable_encoder(response))
    return response


"""
邀请推广相关
"""


@router.post(
    path='/person/coupon/obtain_filter',
    summary='获取或过滤优惠券',
    description='获取或过滤优惠券',
    response_model=Union[list, dict, List[dict]]
)
@custom_response
@set_lang
async def get_or_filter_coupon(customer_coupon_filter: CustomerCouponFilterDto = Body(..., description='优惠券筛选条件'), env: Environment = Depends(odoo_env),
                               Accept_Language: Optional[str] = Header()):
    func = CenterAreaFunc(env)
    response = func.get_or_filter_coupon(customer_coupon_filter)
    result = [CouponBase(__from_odoo=record, __env=env) for record in response]
    result = CommonResponse(code='200', msg='success', data=jsonable_encoder(result))
    return result
